- /* sstring.cpp by K.Tsuru */
- // function ID = 601, 602, 603 DRADIX
- /***************************************************************************
- StringToNumber class
- Provides a conversion string to number.
- It identifies a number which has a point or an exponent with the REAL type,
- other with the DEC_INT one, however it can be substituted for both the SLong
- and SDouble variable.
- *****************************************************************************/
- #ifndef SN_H
- #include "sn.h"
- #endif
- /*
- It removes the sign, exponent, etc.
- */
- // function ID = 601
- void StringToNumber::GetDigit(const char* src){
- uint buffSize = strlen(src)+1;
- char* buff = new char[buffSize]; //work area
- char* pt;
- int c, sgn;
- uint k = 0;
- intLen = decLen = expLen = 0;
-
- //It removes the top spaces, tabs, zeros and sign.
- do{
- c = *(src++);
- } while( c && (!isdigit(c)) && c != '-' && c != '+' && c != '.');
- //It detects the sign.
- switch(c){
- // *src points the next of sign.
- case '+' : sgn = 1; break;
- case '-' : sgn = -1; break;
- case '\0' : snSign = 0; goto Ret;
- default : sgn = 1; src--; break; //a digit, back
- }
- snSign = sgn;
- //It detects an integral part.
- SetType(DEC_INT);
- pt = buff;
- do{
- c = *(src++);
- if(isdigit(c)){
- *(pt++) = c; k++;
- }
- } while( c && !( c == 'e' || c == 'E' || c == '.') );
-
- //If k == 0 the intPart[] is empty.
- *pt = '\0'; intPart = new char[k+1];
- strcpy(intPart, buff); intLen = k;
-
- if(c == '\0') goto Ret; //integral part only
- //It detects a decimal part.
- SetType(REAL);
- pt = buff; //put into buff[]
- k = 0;
- while( c && !( c == 'e' || c == 'E' ) ){
- c = *(src++);
- if(isdigit(c)){
- *(pt++) = c; k++;
- } else if(c == '.') SetError( SYNTAX_ERR,"too many point.", 61);
- }
- if(k){
- *pt = '\0'; decPart = new char[k+1];
- strcpy(decPart, buff); decLen = k;
- }
- if(c == '\0') goto Ret; // "iii.ddddd" form
-
- //It detects an exponent.
- //It does not check that the value can be expressed by a long variable or not.
- expLen = strlen(src);
- expPart = new char[expLen + 1];
- strcpy(expPart, src);
- Ret:
- delete[] buff;
- }
-
- static int rest(long s, int q){
- if( (s % q) == 0 ) return 0;
- return int(q - s % q);
- }
- // function ID = 602
- static const char* func = "StringToNumber";
- void StringToNumber::Analyze(){
- fType V = fTypeMax;
- char* pt;
-
- uint num_len = intLen + decLen; //length of number part
- uint total_len = num_len + expLen, k;
-
- if( !total_len ) V = 0; // strNum[] is empty
- else if( (intLen <= (uint)DFIGURES) && (Type() == DEC_INT) ){
- //The length of strNum is is smaller than four.
- //The sign in the intPart was already removed.
- V = atoF(intPart);
- if(V == 0) snSign = ZERO;
- }
- if( V < Radix() ){ //one figure integer
- valloc(minArraySize, 0); //sign = 0;
- figure[0] = V; SetSign(snSign);
- return;
- }
-
- //It detects the length of integral and decimal part.
- //V = aaa.bbbbcccc...zzzz * 10^x
- char* buff = new char[num_len+2*DFIGURES+1]; //work area
- *buff = '\0'; //Let be empty to enable to use "strcat" even if add0==0 in below.
-
- if(Type() == REAL){
- long exp;
- int add0;
- //It converts into V = [0.]00aa|abbb|bccc|cddd|....|z000 * DRADIX^snRDXExp.
- exp = expLen ? atol(expPart) : 0;
- exp += (long)intLen; // [0.]aaabbb...*10^(e+i)
- //the number of top zeros, DFIGURES > add0 >= 0
- add0 = exp > 0 ? rest(exp, DFIGURES) : (int)(labs(exp) % DFIGURES);
- if(add0){ // add0 > 0
- exp += add0;
- pt = buff;
- while(add0--) *(pt++) = '0';
- *pt = '\0';
- }
- //It copies the integral and decimal part continuously.
- strcat(buff, intPart); // intPart != NULL
- if(decPart != NULL) strcat(buff, decPart);
- //It adds zeros to the end.
- k = strlen(buff);
- if( ( add0 = rest(k, DFIGURES) ) != 0 ){ // k > 0 --> add0 >=0
- pt = strchr(buff, 0);
- while(add0--) *(pt++) = '0';
- *pt = '\0';
- }
- //the exponent in DRADIX.
- snRdxExp = int(exp/DFIGURES);
- num_len = strlen(buff);
- } else { //DEC_INT type
- int addspc; //the number of top spaces
- num_len = strlen(intPart);
- if( (addspc = rest(num_len, DFIGURES)) != 0 ){
- pt = buff;
- while(addspc--) *(pt++) = ' ';
- *pt = '\0';
- } // *buff = '\0';
- strcat(buff, intPart); // intPart != NULL
- num_len = strlen(buff);
- }
-
- //It puts into figure[] from top.
- char fig[DFIGURES + 1]; //work area
- uint rdx_figs;
- // rdx_figs < INT_MAX because num_len < UINT_MAX has been checked.
- pt = buff;
- rdx_figs = max(num_len/DFIGURES, 1u);
- #ifndef NDEBUG
- assert(num_len && !(num_len % DFIGURES) );
- #endif
- //Figures in DRADIX num_len is a multiple of DFIGURES.
-
- if(Type() == DEC_INT){
- if(rdx_figs > MaxSize()) SetError(OVERFLOW_ERR, func, 602);
- int j;
-
- valloc(rdx_figs, 0); //It allocates the memory of figure[].
- for( j = rdx_figs - 1; j >= 0 ; j--){
- strncpy(fig, pt, DFIGURES);
- fig[DFIGURES] = '\0';
- figure[j] = atoF(fig);
- pt += DFIGURES;
- }
- }else{ //REAL
- uint i, vsz = min(rdx_figs+1u, MaxSize()); //It adds one for figure[0].
- valloc(vsz, 0);
- for( i = 1u; i < vsz; i++){
- strncpy(fig, pt, DFIGURES);
- fig[DFIGURES] = '\0';
- figure[i] = atoF(fig);
- pt += DFIGURES;
- }
- }
-
- delete[] buff;
- SetSign(snSign);
- CheckArray(602);
- }
- // function ID = 603
- // destructor
- StringToNumber::~StringToNumber(){
- delete[] intPart; delete[] decPart; delete[] expPart;
- }
sstring.cpp : last modifiled at 2017/03/17 11:10:49(5,441 bytes)
created at 2016/04/11 11:36:47
The creation time of this html file is 2017/10/27 10:59:17 (Fri Oct 27 10:59:17 2017).